package site.xuxingcan;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by xuxingcan on 16-12-28.
 */
public class GUI {
    private JPanel panel1;
    private JTable table1;
    private JTextField textField1;
    private JLabel ipLabel;
    private JLabel socketLabel;
    private HashMap<String, Thread> waittingThreadHashMap = new HashMap<>();
    private HashMap<String, ExecutorService> postExecutorServiceHashMap = new HashMap<>();
    private long spTime = 1000;

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel("com.jtattoo.plaf.fast.FastLookAndFeel");
        FontUIResource fontUIResource = new FontUIResource(new Font("宋体", Font.PLAIN, 12));
        for (Enumeration keys = UIManager.getDefaults().keys(); keys.hasMoreElements(); ) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                UIManager.put(key, fontUIResource);
            }
        }
//        long currentTime = getWebsiteDatetime("http://www.baidu.com");
//        long time = data2Time("yyyy-MM-dd HH:mm:ss", "2017-01-10 00:00:00");
//        if (currentTime < time) {
//        } else {
//            throw new Exception();
//        }
        JFrame frame = new JFrame("GUI");
        frame.setContentPane(new GUI().panel1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private GUI() {
        setDevicesTable();
        start();
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress();//获得本机IP
            ipLabel.setText(ip);
//            String[] ips = getAllLocalHostIP();
//            String msg = "";
//            for (String ip : ips) {
//                msg += ip + "\r\n";
//            }
//            ipLabel.setText(msg);
        } catch (Exception e) {
            ipLabel.setText("获取本机IP失败");
            e.printStackTrace();
        }
    }

    private static long data2Time(String format, String time) {
//        SimpleDateFormat sdr = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        SimpleDateFormat sdr = new SimpleDateFormat(format);
        Date date;
        try {
            date = sdr.parse(time);
            long l = date.getTime();
            return l;
        } catch (ParseException e) {
            e.printStackTrace();
            return Long.MAX_VALUE;
        }
    }

    private static long getWebsiteDatetime(String webUrl) {
        try {
            URL url = new URL(webUrl);// 取得资源对象
            URLConnection uc = url.openConnection();// 生成连接对象
            uc.connect();// 发出连接
            long ld = uc.getDate();// 读取网站日期时间
//            Date date = new Date(ld);// 转换为标准时间对象
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);// 输出北京时间
            return ld;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public String getLocalHostName() {
        String hostName;
        try {
            InetAddress addr = InetAddress.getLocalHost();
            hostName = addr.getHostName();
        } catch (Exception ex) {
            hostName = "";
        }
        return hostName;
    }

    public String[] getAllLocalHostIP() {
        String[] ret = null;
        try {
            String hostName = getLocalHostName();
            if (hostName.length() > 0) {
                InetAddress[] addrs = InetAddress.getAllByName(hostName);
                if (addrs.length > 0) {
                    ret = new String[addrs.length];
                    for (int i = 0; i < addrs.length; i++) {
                        ret[i] = addrs[i].getHostAddress();
                    }
                }
            }

        } catch (Exception ex) {
            ret = null;
        }
        return ret;
    }

    private void setDevicesTable() {
        String[] headers = {"状态", "序号", "订单号"};
        DefaultTableModel model = new DefaultTableModel(null, headers) {
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        table1.setModel(model);
        final JPopupMenu jPopupMenu = new JPopupMenu();
        JMenuItem jMenuItem = new JMenuItem("删除当前订单");
        jMenuItem.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (table1.getSelectedRowCount() == 1) {
                    String zbShipmentId = (String) table1.getModel().getValueAt(table1.getSelectedRow(), 0);
                    try {
                        waittingThreadHashMap.remove(zbShipmentId).interrupt();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    try {
                        postExecutorServiceHashMap.remove(zbShipmentId).shutdownNow();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    DefaultTableModel tableModel = (DefaultTableModel) table1.getModel();
                    tableModel.removeRow(table1.getSelectedRow());
                }
            }
        });
        jPopupMenu.add(jMenuItem);
        table1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == 3 && table1.getSelectedColumnCount() > 0) {
                    jPopupMenu.show(table1, e.getX(), e.getY());
                }
            }
        });
    }

    private void addNewOrder(final String userId, final String token, String zbShipmentId) {
        try {
            if (zbShipmentId == null || zbShipmentId.length() == 0) {
                return;
            }
            String orderListJson = getOrderList(userId, token);
            ArrayList<OrderModel> list = gson.fromJson(orderListJson,
                    new TypeToken<List<OrderModel>>() {
                    }.getType());
            for (final OrderModel orderModel : list) {
                if (zbShipmentId.equalsIgnoreCase(orderModel.getZbShipmentId() + "")) {

                    DefaultTableModel tableModel = (DefaultTableModel) table1.getModel();
                    String[] arr = new String[3];
                    arr[0] = "倒计时" + orderModel.getTenderInterval() / 1000 + "秒";
                    arr[1] = String.valueOf(orderModel.getZbShipmentId());
                    arr[2] = String.valueOf(orderModel.getShipmentCode());
                    tableModel.addRow(arr);
                    table1.setModel(tableModel);

                    Thread mThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (orderModel.getTenderInterval() - spTime > 0) {
                                    Thread.sleep(orderModel.getTenderInterval() - spTime);
                                }
                                changeStatus(orderModel.getZbShipmentId() + "", "开始抢单");
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            Thread.sleep(2 * spTime);
                                            postExecutorServiceHashMap.remove(orderModel.getZbShipmentId()).shutdownNow();
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                        changeStatus(orderModel.getZbShipmentId() + "", "抢单完毕");
                                    }
                                }).start();
                                orderConfirm(userId, token, orderModel.getZbShipmentId() + "");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                    waittingThreadHashMap.put(zbShipmentId, mThread);
                    mThread.start();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void changeStatus(String zbShipmentId, String status) {
        for (int i = 0; i < table1.getRowCount(); i++) {
            if (table1.getValueAt(i, 1).equals(zbShipmentId)) {
                table1.setValueAt(status, i, 0);
                break;
            }
        }
    }

    public void orderConfirm(String userId, String token, String zbShipmentId) {
        HttpPost httpPost = new HttpPost("http://223.99.167.71:8081/xwtms/remote.app");
        httpPost.addHeader("userId", userId);
        httpPost.addHeader("token", token);
        httpPost.addHeader("method", "orderTenderConfirm");
        httpPost.addHeader("lisence", "null");
        httpPost.addHeader("zbShipmentId", zbShipmentId);
        httpPost.addHeader("beChecked", "true");
        httpPost.addHeader("Connection", "keep-alive");

        List nvps = new ArrayList();
        nvps.add(new BasicNameValuePair("userId", userId));
        nvps.add(new BasicNameValuePair("token", token));
        nvps.add(new BasicNameValuePair("method", "orderTenderConfirm"));
        nvps.add(new BasicNameValuePair("lisence", "null"));
        nvps.add(new BasicNameValuePair("zbShipmentId", zbShipmentId));
        nvps.add(new BasicNameValuePair("beChecked", "true"));
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        int num = 1000;
        try {
            num = Integer.parseInt(textField1.getText());
        } catch (Exception e) {
            e.printStackTrace();
        }
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(4 * num);
        cm.setDefaultMaxPerRoute(num);
        HttpHost remotehost = new HttpHost("223.99.167.71", 8081);
        cm.setMaxPerRoute(new HttpRoute(remotehost), num);
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();
        int length = 10 * num;

        PostRunnable[] runnables = new PostRunnable[length];

        for (int i = 0; i < runnables.length; i++) {
            runnables[i] = new PostRunnable(httpClient, httpPost);
        }
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        postExecutorServiceHashMap.put(zbShipmentId, cachedThreadPool);
        for (int j = 0; j < runnables.length; j++) {
            cachedThreadPool.execute(runnables[j]);
        }
    }

    public String getOrderList(String userId, String token) {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost("http://223.99.167.71:8081/xwtms/remote.app");
        httpPost.addHeader("userId", userId);
        httpPost.addHeader("token", token);
        httpPost.addHeader("method", "getOrderTenderListByPager");
        httpPost.addHeader("pageSize", "100");
        httpPost.addHeader("currentSize", "0");
        httpPost.addHeader("Connection", "keep-alive");

        List nvps = new ArrayList();
        nvps.add(new BasicNameValuePair("userId", userId));
        nvps.add(new BasicNameValuePair("token", token));
        nvps.add(new BasicNameValuePair("method", "getOrderTenderListByPager"));
        nvps.add(new BasicNameValuePair("pageSize", "50"));
        nvps.add(new BasicNameValuePair("currentSize", "0"));
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        CloseableHttpResponse response2 = null;
        try {
            response2 = httpclient.execute(httpPost);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String result = "";
        try {
            HttpEntity entity2 = response2.getEntity();

            BufferedReader in = new BufferedReader(new InputStreamReader(entity2
                    .getContent()));
            String line;
            while ((line = in.readLine()) != null) {
                result = result + line;
            }

            result = URLDecoder.decode(result, "UTF-8");
            try {
                JSONObject jsonObject = JSONObject.parseObject(result);
                String type = jsonObject.getString("type");
                String tempStr = jsonObject.getString("message").replaceAll("(\n)", "");

                JSONArray jsonArrayMessage = JSON.parseArray(tempStr);
                String jsonStringMessage = jsonObject.getString("message");

                return jsonStringMessage;
            } catch (JSONException e) {
                e.printStackTrace();

                EntityUtils.consume(entity2);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                response2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static ServerSocket serverSocket = null;
    private static Gson gson = new Gson();

    public void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(8191);
                    while (true) {
                        final Socket socket = serverSocket.accept();
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    SocketHelper socketHelper = new SocketHelper(socket);
                                    Gson gson = new Gson();
                                    SimpleDateFormat sdr = new SimpleDateFormat("HH:mm:ss");
                                    socketLabel.setText("最新链接:" + sdr.format(System.currentTimeMillis()));
                                    while (true) {
                                        String s = socketHelper.readLine();
                                        if (s == null || s.length() == 0) {
                                            break;
                                        }
                                        Model model = gson.fromJson(s, Model.class);
                                        if (model == null) {
                                            continue;
                                        }
                                        if ("heartBeat".equalsIgnoreCase(model.msg)) {
                                            socketHelper.writeLineAndFlush("heartBeat");
                                            continue;
                                        }
                                        if (model.msg == null || model.msg.length() == 0) {
                                            if (model.Token != null && model.Token.length() != 0
                                                    && model.userId != null && model.userId.length() != 0
                                                    && model.zbShipmentId != null && model.zbShipmentId.length() != 0) {
                                                addNewOrder(model.userId, model.Token, model.zbShipmentId);
                                                socketHelper.writeLineAndFlush("OK");
                                                continue;
                                            }
                                        }
                                        socketHelper.writeLineAndFlush("nothing");
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }).start();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void stop() {
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
